package com.sangmo.fts.process.receivable.service;

import com.sangmo.boot.framework.common.errors.ServiceException;
import com.sangmo.boot.framework.common.errors.StandardErrors;
import com.sangmo.boot.framework.plugin.dataview.crud.service.BaseViewService;
import com.sangmo.boot.framework.plugin.dataview.data.IDataViewRepo;
import com.sangmo.fts.common.authority.service.AuthorityEntityService;
import com.sangmo.fts.common.utils.RandomUtils;
import com.sangmo.fts.process.receivable.interfaces.RpfWaybillCreation;
import com.sangmo.fts.process.receivable.model.RpfContract;
import com.sangmo.fts.process.receivable.model.RpfContractItem;
import com.sangmo.fts.process.receivable.model.RpfWaybill;
import com.sangmo.fts.process.receivable.model.RpfWaybillItem;
import com.sangmo.fts.process.receivable.repo.RpfWaybillRepo;
import com.sangmo.fts.process.storage.model.CsfContractItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class RpfWaybillEntityService extends AuthorityEntityService<RpfWaybill> {

    @Autowired
    private RpfWaybillRepo rpfWaybillRepo;

    @Autowired
    private RpfContractService rpfContractService;

    @Autowired
    private RpfWaybillItemEntityService rpfWaybillItemEntityService;

    @Override
    protected IDataViewRepo<RpfWaybill> getRepo() {
        return rpfWaybillRepo;
    }

    @Override
    protected void onCreate(RpfWaybill entity, Object bo) {
        super.onCreate(entity, bo);
        entity.setCode(RandomUtils.generateRandomNum(12));
        RpfWaybillCreation creation = (RpfWaybillCreation) bo;
        RpfContract contract = rpfContractService.checkAndGet(entity.getTrainingId(), creation.getContractId());
        entity.setShipper(contract.getSellerId());
        entity.setConsignee(contract.getBuyerId());
        entity.setContractAmount(rpfContractService.calculateContractAmount(creation.getContractId()));
    }

    @Override
    protected void afterCreated(RpfWaybill entity, Object bo) {
        super.afterCreated(entity, bo);
        List<RpfContractItem> contractItems = rpfContractService.listItemsByContractId(entity.getContractId());
        List<RpfWaybillItem> waybillItems = buildRpfWaybillItems(entity.getId(), contractItems);
        rpfWaybillItemEntityService.saveAll(waybillItems);
    }

    private List<RpfWaybillItem> buildRpfWaybillItems(Long waybillId, List<RpfContractItem> contractItems) {
        List<RpfWaybillItem> waybillItems = new ArrayList<>();
        for (RpfContractItem contractItem : contractItems) {
            RpfWaybillItem item = RpfWaybillItem.fromContractItem(contractItem);
            item.setWaybillId(waybillId);
            waybillItems.add(item);
        }
        return waybillItems;
    }

    @Override
    protected void onDelete(RpfWaybill entity) {
        super.onDelete(entity);
        if (!RpfWaybill.States.PENDING.equals(entity.getState())) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.rpfWaybill.remove.permit.disabled");
        }
    }

    public RpfWaybill findByContractId(Long contractId) {
        return rpfWaybillRepo.findByContractId(contractId);
    }

    public RpfWaybill findAvailableByContractId(Long contractId, Long trainingId) {
        RpfWaybill rpfWaybill = rpfWaybillRepo.findAvailableByContractId(contractId, trainingId);
        if (null == rpfWaybill) {
            throw new ServiceException(StandardErrors.EXTERNAL_ERROR.getStatus(), "error.rpfWaybill.not.available");
        }
        return rpfWaybill;
    }
}
